<?php

namespace app\controller\admin;

use app\model\PromotionModel;
use app\model\PromotionItemModel;
use support\Request;
use app\exception\BusinessException;
use hg\apidoc\annotation as Apidoc;

/**
 * @Apidoc\Title("促销活动管理")
 * @Apidoc\Group("admin")
 */
class PromotionController
{
    /**
     * @Apidoc\Title("获取促销活动列表")
     * @Apidoc\Method("GET")
     * @Apidoc\Url("/admin/promotion/list")
     * @Apidoc\Param("page", type="int", default=1, desc="页码")
     * @Apidoc\Param("page_size", type="int", default=15, desc="每页数量")
     * @Apidoc\Param("name", type="string", desc="活动名称")
     * @Apidoc\Param("type", type="int", desc="活动类型")
     * @Apidoc\Param("status", type="int", desc="状态")
     * @Apidoc\Param("start_time", type="string", desc="开始时间")
     * @Apidoc\Param("end_time", type="string", desc="结束时间")
     */
    public function list(Request $request)
    {
        $params = $request->all();
        $page = $request->get('page', 1);
        $pageSize = $request->get('page_size', 15);
        
        $query = PromotionModel::query();
        
        // 搜索条件
        if (!empty($params['name'])) {
            $query->where('name', 'like', "%{$params['name']}%");
        }
        if (isset($params['type'])) {
            $query->where('type', $params['type']);
        }
        if (isset($params['status'])) {
            $query->where('status', $params['status']);
        }
        if (!empty($params['start_time'])) {
            $query->where('start_time', '>=', $params['start_time']);
        }
        if (!empty($params['end_time'])) {
            $query->where('end_time', '<=', $params['end_time']);
        }
        
        $promotions = $query->orderBy('id', 'desc')
            ->paginate($pageSize, ['*'], 'page', $page);
            
        return json(['code' => 0, 'msg' => 'success', 'data' => $promotions]);
    }
    
    /**
     * @Apidoc\Title("获取促销活动详情")
     * @Apidoc\Method("GET")
     * @Apidoc\Url("/admin/promotion/detail/{id}")
     * @Apidoc\Param("id", type="int", require=true, desc="促销活动ID")
     */
    public function detail($id)
    {
        $promotion = PromotionModel::with(['items.product', 'items.sku'])
            ->find($id);
        
        if (!$promotion) {
            throw new BusinessException('促销活动不存在');
        }
        
        return json(['code' => 0, 'msg' => 'success', 'data' => $promotion]);
    }
    
    /**
     * @Apidoc\Title("创建促销活动")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/admin/promotion/store")
     * @Apidoc\ParamType("json")
     * @Apidoc\Param("name", type="string", require=true, desc="活动名称")
     * @Apidoc\Param("type", type="int", require=true, desc="活动类型：1限时特价，2满减活动，3套餐搭配")
     * @Apidoc\Param("start_time", type="string", require=true, desc="开始时间")
     * @Apidoc\Param("end_time", type="string", require=true, desc="结束时间")
     * @Apidoc\Param("description", type="string", desc="活动描述")
     * @Apidoc\Param("rules", type="object", desc="活动规则")
     */
    public function store(Request $request)
    {
        $data = $request->post();
        
        try {
            // 验证数据
            $this->validatePromotionData($data);
            
            // 创建促销活动
            $promotion = new PromotionModel();
            $promotion->fill($data);
            $promotion->save();
            
            return json(['code' => 0, 'msg' => '创建成功', 'data' => $promotion]);
        } catch (\Exception $e) {
            throw new BusinessException($e->getMessage());
        }
    }
    
    /**
     * @Apidoc\Title("更新促销活动")
     * @Apidoc\Method("PUT")
     * @Apidoc\Url("/admin/promotion/update/{id}")
     * @Apidoc\Param("id", type="int", require=true, desc="促销活动ID")
     * @Apidoc\ParamType("json")
     * @Apidoc\Param("name", type="string", desc="活动名称")
     * @Apidoc\Param("type", type="int", desc="活动类型：1限时特价，2满减活动，3套餐搭配")
     * @Apidoc\Param("start_time", type="string", desc="开始时间")
     * @Apidoc\Param("end_time", type="string", desc="结束时间")
     * @Apidoc\Param("description", type="string", desc="活动描述")
     * @Apidoc\Param("rules", type="object", desc="活动规则")
     */
    public function update(Request $request, $id)
    {
        $data = $request->post();
        
        try {
            $promotion = PromotionModel::find($id);
            
            if (!$promotion) {
                throw new BusinessException('促销活动不存在');
            }
            
            // 验证数据
            $this->validatePromotionData($data, $promotion);
            
            // 更新促销活动
            $promotion->fill($data);
            $promotion->save();
            
            return json(['code' => 0, 'msg' => '更新成功', 'data' => $promotion]);
        } catch (\Exception $e) {
            throw new BusinessException($e->getMessage());
        }
    }
    
    /**
     * @Apidoc\Title("删除促销活动")
     * @Apidoc\Method("DELETE")
     * @Apidoc\Url("/admin/promotion/destroy/{id}")
     * @Apidoc\Param("id", type="int", require=true, desc="促销活动ID")
     */
    public function destroy($id)
    {
        try {
            $promotion = PromotionModel::find($id);
            
            if (!$promotion) {
                throw new BusinessException('促销活动不存在');
            }
            
            // 检查是否已开始
            if ($promotion->start_time <= date('Y-m-d H:i:s')) {
                throw new BusinessException('活动已开始，无法删除');
            }
            
            // 删除促销商品
            PromotionItemModel::where('promotion_id', $id)->delete();
            
            // 删除促销活动
            $promotion->delete();
            
            return json(['code' => 0, 'msg' => '删除成功']);
        } catch (\Exception $e) {
            throw new BusinessException($e->getMessage());
        }
    }
    
    /**
     * @Apidoc\Title("修改促销活动状态")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/admin/promotion/status/{id}")
     * @Apidoc\Param("id", type="int", require=true, desc="促销活动ID")
     * @Apidoc\ParamType("json")
     * @Apidoc\Param("status", type="int", require=true, desc="状态：0禁用，1启用")
     */
    public function status(Request $request, $id)
    {
        try {
            $promotion = PromotionModel::find($id);
            
            if (!$promotion) {
                throw new BusinessException('促销活动不存在');
            }
            
            $status = $request->post('status');
            
            if (!in_array($status, [0, 1])) {
                throw new BusinessException('状态值不正确');
            }
            
            $promotion->status = $status;
            $promotion->save();
            
            return json(['code' => 0, 'msg' => '操作成功']);
        } catch (\Exception $e) {
            throw new BusinessException($e->getMessage());
        }
    }
    
    /**
     * @Apidoc\Title("促销活动统计")
     * @Apidoc\Method("GET")
     * @Apidoc\Url("/admin/promotion/statistics")
     * @Apidoc\Param("start_time", type="string", desc="开始时间")
     * @Apidoc\Param("end_time", type="string", desc="结束时间")
     */
    public function statistics(Request $request)
    {
        $startTime = $request->get('start_time', date('Y-m-d'));
        $endTime = $request->get('end_time', date('Y-m-d'));
        
        // 活动总数
        $totalCount = PromotionModel::whereBetween('created_at', [$startTime, $endTime])
            ->count();
            
        // 进行中的活动数
        $ongoingCount = PromotionModel::where('status', 1)
            ->where('start_time', '<=', date('Y-m-d H:i:s'))
            ->where('end_time', '>=', date('Y-m-d H:i:s'))
            ->count();
            
        // 已结束的活动数
        $endedCount = PromotionModel::where('end_time', '<', date('Y-m-d H:i:s'))
            ->count();
            
        // 各类型活动数量
        $typeCount = PromotionModel::whereBetween('created_at', [$startTime, $endTime])
            ->selectRaw('type, count(*) as count')
            ->groupBy('type')
            ->get()
            ->pluck('count', 'type')
            ->toArray();
            
        return json([
            'code' => 0,
            'msg' => 'success',
            'data' => [
                'total_count' => $totalCount,
                'ongoing_count' => $ongoingCount,
                'ended_count' => $endedCount,
                'type_count' => $typeCount,
            ]
        ]);
    }
    
    /**
     * @Apidoc\Title("获取促销商品列表")
     * @Apidoc\Method("GET")
     * @Apidoc\Url("/admin/promotion/item/list")
     * @Apidoc\Param("promotion_id", type="int", require=true, desc="促销活动ID")
     * @Apidoc\Param("page", type="int", default=1, desc="页码")
     * @Apidoc\Param("page_size", type="int", default=15, desc="每页数量")
     */
    public function itemList(Request $request)
    {
        $promotionId = $request->get('promotion_id');
        $page = $request->get('page', 1);
        $pageSize = $request->get('page_size', 15);
        
        $items = PromotionItemModel::with(['product', 'sku'])
            ->where('promotion_id', $promotionId)
            ->orderBy('sort', 'asc')
            ->orderBy('id', 'desc')
            ->paginate($pageSize, ['*'], 'page', $page);
            
        return json(['code' => 0, 'msg' => 'success', 'data' => $items]);
    }
    
    /**
     * @Apidoc\Title("添加促销商品")
     * @Apidoc\Method("POST")
     * @Apidoc\Url("/admin/promotion/item/store")
     * @Apidoc\ParamType("json")
     * @Apidoc\Param("promotion_id", type="int", require=true, desc="促销活动ID")
     * @Apidoc\Param("product_id", type="int", require=true, desc="商品ID")
     * @Apidoc\Param("sku_id", type="int", desc="商品SKU ID")
     * @Apidoc\Param("original_price", type="number", require=true, desc="原价")
     * @Apidoc\Param("promotion_price", type="number", require=true, desc="促销价")
     * @Apidoc\Param("stock", type="int", require=true, desc="活动库存")
     * @Apidoc\Param("limit", type="int", desc="每人限购数量")
     * @Apidoc\Param("sort", type="int", desc="排序")
     */
    public function itemStore(Request $request)
    {
        $data = $request->post();
        
        try {
            // 验证数据
            $this->validatePromotionItemData($data);
            
            // 创建促销商品
            $item = new PromotionItemModel();
            $item->fill($data);
            $item->save();
            
            return json(['code' => 0, 'msg' => '添加成功', 'data' => $item]);
        } catch (\Exception $e) {
            throw new BusinessException($e->getMessage());
        }
    }
    
    /**
     * @Apidoc\Title("更新促销商品")
     * @Apidoc\Method("PUT")
     * @Apidoc\Url("/admin/promotion/item/update/{id}")
     * @Apidoc\Param("id", type="int", require=true, desc="促销商品ID")
     * @Apidoc\ParamType("json")
     * @Apidoc\Param("original_price", type="number", desc="原价")
     * @Apidoc\Param("promotion_price", type="number", desc="促销价")
     * @Apidoc\Param("stock", type="int", desc="活动库存")
     * @Apidoc\Param("limit", type="int", desc="每人限购数量")
     * @Apidoc\Param("sort", type="int", desc="排序")
     */
    public function itemUpdate(Request $request, $id)
    {
        $data = $request->post();
        
        try {
            $item = PromotionItemModel::find($id);
            
            if (!$item) {
                throw new BusinessException('促销商品不存在');
            }
            
            // 验证数据
            $this->validatePromotionItemData($data, $item);
            
            // 更新促销商品
            $item->fill($data);
            $item->save();
            
            return json(['code' => 0, 'msg' => '更新成功', 'data' => $item]);
        } catch (\Exception $e) {
            throw new BusinessException($e->getMessage());
        }
    }
    
    /**
     * @Apidoc\Title("删除促销商品")
     * @Apidoc\Method("DELETE")
     * @Apidoc\Url("/admin/promotion/item/destroy/{id}")
     * @Apidoc\Param("id", type="int", require=true, desc="促销商品ID")
     */
    public function itemDestroy($id)
    {
        try {
            $item = PromotionItemModel::find($id);
            
            if (!$item) {
                throw new BusinessException('促销商品不存在');
            }
            
            // 检查活动是否已开始
            $promotion = PromotionModel::find($item->promotion_id);
            if ($promotion && $promotion->start_time <= date('Y-m-d H:i:s')) {
                throw new BusinessException('活动已开始，无法删除商品');
            }
            
            $item->delete();
            
            return json(['code' => 0, 'msg' => '删除成功']);
        } catch (\Exception $e) {
            throw new BusinessException($e->getMessage());
        }
    }
    
    /**
     * 验证促销活动数据
     */
    private function validatePromotionData($data, $promotion = null)
    {
        if (empty($data['name'])) {
            throw new BusinessException('活动名称不能为空');
        }
        
        if (empty($data['type']) || !in_array($data['type'], [1, 2, 3])) {
            throw new BusinessException('活动类型不正确');
        }
        
        if (empty($data['start_time'])) {
            throw new BusinessException('开始时间不能为空');
        }
        
        if (empty($data['end_time'])) {
            throw new BusinessException('结束时间不能为空');
        }
        
        if (strtotime($data['start_time']) >= strtotime($data['end_time'])) {
            throw new BusinessException('开始时间必须小于结束时间');
        }
        
        if ($data['type'] == 2) {
            // 满减活动必须设置规则
            if (empty($data['rules'])) {
                throw new BusinessException('请设置满减规则');
            }
            
            $rules = is_array($data['rules']) ? $data['rules'] : json_decode($data['rules'], true);
            
            if (empty($rules)) {
                throw new BusinessException('满减规则不能为空');
            }
            
            foreach ($rules as $rule) {
                if (!isset($rule['full']) || !isset($rule['reduce'])) {
                    throw new BusinessException('满减规则格式不正确');
                }
                
                if ($rule['full'] <= 0 || $rule['reduce'] <= 0) {
                    throw new BusinessException('满减金额必须大于0');
                }
                
                if ($rule['reduce'] >= $rule['full']) {
                    throw new BusinessException('减免金额不能大于等于满减金额');
                }
            }
        }
    }
    
    /**
     * 验证促销商品数据
     */
    private function validatePromotionItemData($data, $item = null)
    {
        if (empty($data['promotion_id'])) {
            throw new BusinessException('促销活动ID不能为空');
        }
        
        if (empty($data['product_id'])) {
            throw new BusinessException('商品ID不能为空');
        }
        
        if ($data['original_price'] <= 0) {
            throw new BusinessException('原价必须大于0');
        }
        
        if ($data['promotion_price'] <= 0) {
            throw new BusinessException('促销价必须大于0');
        }
        
        if ($data['promotion_price'] >= $data['original_price']) {
            throw new BusinessException('促销价必须小于原价');
        }
        
        if ($data['stock'] < 0) {
            throw new BusinessException('活动库存不能小于0');
        }
        
        if (!empty($data['limit']) && $data['limit'] <= 0) {
            throw new BusinessException('每人限购数量必须大于0');
        }
        
        // 检查商品是否已参加其他进行中的活动
        if (!$item) {
            $exists = PromotionItemModel::whereHas('promotion', function ($query) {
                $query->where('status', 1)
                    ->where('start_time', '<=', date('Y-m-d H:i:s'))
                    ->where('end_time', '>=', date('Y-m-d H:i:s'));
            })
            ->where('product_id', $data['product_id'])
            ->when(!empty($data['sku_id']), function ($query) use ($data) {
                $query->where('sku_id', $data['sku_id']);
            })
            ->exists();
            
            if ($exists) {
                throw new BusinessException('该商品已参加其他进行中的活动');
            }
        }
    }
} 